import 'package:lib_util/utils/utils.dart';
import 'package:objectbox/objectbox.dart';
import 'package:lib_language/lib_language.dart';
import '../../../objectbox.dart';
import '../../../objectbox.g.dart';
import '../basemodel.dart';
import '../../config.dart';
import '../../network.dart';
import '../wallet_info_model/wallet_info_model.dart';

@Entity()
class CustomEVMChain {
  @Id()
  int id = 0;

  @Unique()
  String name;
  String symbol;
  String rpc;
  String blockExplorerUrl;
  int chainId;
  String blockApiUrl;

  CustomEVMChain(
      {this.id = 0,
      required this.name,
      required this.symbol,
      required this.rpc,
      required this.blockExplorerUrl,
      required this.chainId,
      required this.blockApiUrl});
}

class CustomEVMChainModel extends BaseModel<CustomEVMChain> {
  CustomEVMChainModel(Box<CustomEVMChain> box) : super(box);

  List<CustomEVMChain> presetCustomList = [
    // CustomEVMChain(
    //     name: '${Config.customChainShortNamePrefix}BSC Testnet',
    //     symbol: 'tBNB',
    //     rpc: 'https://data-seed-prebsc-1-s1.binance.org:8545',
    //     blockExplorerUrl: 'https://testnet.bscscan.com',
    //     chainId: 97,
    //     blockApiUrl: 'https://api-testnet.bscscan.com')
  ];

  bool isPresetCustomEVMChain(Chain c) {
    for (var p in presetCustomList) {
      if (p.name == c.shortName) {
        return true;
      }
    }
    return false;
  }

  CustomEVMChain getCustomEVMChainByName(String name) {
    return box.query(CustomEVMChain_.name.equals(name)).build().findFirst()!;
  }

  deleteCustomEVMChain(Chain c) {
    List<WalletInfo> walletInfoList = ObjectBox().getWalletInfoListByChain(c);
    if (walletInfoList.isEmpty) {
      //删除网络
      box.removeMany(box
          .query(CustomEVMChain_.name.equals(c.shortName))
          .build()
          .findIds());
      //删除节点
      ObjectBox().nodeInfoModel.deleteAllNodeInfo(c.shortName);
      //移除内存中的旧Chain
      ChainList().chains.remove(c);
    } else {
      throw LocaleKeys.shanchuwangluotishi.tr();
    }
  }

  initCustomEVMChain() {
    List<CustomEVMChain> list = box.getAll();
    list.insertAll(0, presetCustomList);
    List<CustomEVMChain> noExistList = list.where((element) {
      bool exist = false;
      for (var c in ChainList().chains) {
        if (c.shortName == element.name) {
          exist = true;
          break;
        }
      }
      return !exist;
    }).toList(growable: false);
    // 添加
    ChainList().addAllChains(noExistList
        .map((e) => convertCustomEVMChain(e))
        .toList(growable: false));
  }

  Chain convertCustomEVMChain(CustomEVMChain cc) {
    return Chain(
        type: ChainType.eth,
        name: cc.name.substring(Config.customChainShortNamePrefix.length),
        shortName: cc.name,
        symbol: cc.symbol,
        logo: "",
        derivePath: ChainList.derivePathEVM,
        blockExplorerUrl: cc.blockExplorerUrl,
        blockExplorerApi: cc.blockApiUrl,
        evmInfo: EVMInfo(chainId: cc.chainId, rpcList: [cc.rpc]));
  }

  bool addCustomEVMChain(CustomEVMChain chain, {String? oldName}) {
    if (box.query(CustomEVMChain_.name.equals(chain.name)).build().count() >
        0) {
      throw 'this name already exist';
    }

    if (Utils.isNotEmpty(oldName)) {
      //更新
      //String name;
      //   String symbol;
      //   String rpc;
      //   String blockExplorerUrl;
      //   int chainId;
      //   String blockApiUrl;
      CustomEVMChain oldCC = getCustomEVMChainByName(oldName!);
      oldCC.name = chain.name;
      oldCC.symbol = chain.symbol;
      oldCC.rpc = chain.rpc;
      oldCC.blockExplorerUrl = chain.blockExplorerUrl;
      oldCC.chainId = chain.chainId;
      oldCC.blockApiUrl = chain.blockApiUrl;

      box.put(oldCC, mode: PutMode.update);

      //移除内存中的旧Chain
      Chain oldChain = ChainList()
          .chains
          .firstWhere((element) => element.shortName == oldName);
      ChainList().removeChain(oldChain);

      //chain short name 已更新
      if (oldName != chain.name) {
        //更新钱包
        ObjectBox().walletInfoModel.updateChainShortName(oldName, chain.name);
        //删除节点
        ObjectBox().nodeInfoModel.deleteAllNodeInfo(oldName);
      }

      //最后重新初始化链和节点列表
      initCustomEVMChain();
      ObjectBox().nodeInfoModel.initNode();

      return true;
    }

    int cid = box.put(chain);
    if (cid > 0) {
      initCustomEVMChain();
      ObjectBox().nodeInfoModel.initNode();
      return true;
    }
    return false;
  }
}
